﻿using System;
using System.Windows.Forms;
using Microsoft.Practices.RecipeFramework;
using Microsoft.Practices.RecipeFramework.Services;
using Microsoft.Practices.WizardFramework;
using Sixeyed.CodeGeneration.Generation;
using io = System.IO;
using Sixeyed.Guidance.CodeGeneration.Helpers;
using Microsoft.Practices.ComponentModel;

namespace Sixeyed.Guidance.CodeGeneration.CustomWizardPages
{
    /// <summary>
    /// Wizard page for selecting the T4 template used in code generation
    /// </summary>
    [ServiceDependency(typeof(IExecutionService))]
    public partial class SelectTemplate : CodeGenerationPageBase
    {
        private bool _addedBindings;

        /// <summary>
        /// Gets/sets configuration of the T4 template
        /// </summary>
        [RecipeArgument]
        public TemplateConfiguration TemplateConfiguration
        {
            get { return this.GetArgumentValue<TemplateConfiguration>("TemplateConfiguration"); }
            set
            {
                if (value == null)
                {
                    value = new TemplateConfiguration();
                }
                this.SetArgumentValue<TemplateConfiguration>("TemplateConfiguration", value);
                this.AddDataBindings();
            }
        }

        /// <summary>
        /// Constructor with initial state
        /// </summary>
        /// <param name="parent">Parent wizard form</param>
        public SelectTemplate(WizardForm parent) : base(parent)
        {
            InitializeComponent();
            this.SetupFileDialog();            
        }

        /// <summary>
        /// Returns true if a template is selected
        /// </summary>
        public override bool IsDataValid
        {
            get
            {
                return (this.TemplateConfiguration != null && !string.IsNullOrEmpty(this.TemplateConfiguration.TemplatePath));
            }
        }

        private void SetupFileDialog()
        {
            this.openFileDialog1.Filter = "T4 Template files (*.tt)|*.tt";
            this.openFileDialog1.Title = "Select a template file";
            this.openFileDialog1.CheckFileExists = true;
            string initialDirectory = this.GetInitialDirectory();
            if (!string.IsNullOrEmpty(initialDirectory))
            {
                this.openFileDialog1.InitialDirectory = initialDirectory;
            }
        }

        private string GetInitialDirectory()
        {
            GuidancePackage package = (GuidancePackage) this.GetService(typeof(IExecutionService));
            return PathHelper.GetTemplateDirectory(package);
        }

        private void AddDataBindings()
        {
            if (!_addedBindings)
            {
                this.txtTemplatePath.DataBindings.Add("Text", this.TemplateConfiguration, "TemplatePath");
                this.txtClassName.DataBindings.Add("Text", this.TemplateConfiguration, "ClassName");
                this.txtTargetFileExtension.DataBindings.Add("Text", this.TemplateConfiguration, "FileExtension");
                this.txtTargetFilename.DataBindings.Add("Text", this.TemplateConfiguration, "FileName");
                this.txtTargetNamespace.DataBindings.Add("Text", this.TemplateConfiguration, "TargetNamespace");
                _addedBindings = true;
            }
        }

        private void btnSelectTemplate_Click(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                this.txtTemplatePath.Text = this.openFileDialog1.FileName;
            }
        }

        private void txtTemplatePath_TextChanged(object sender, EventArgs e)
        {
            //ES - the databinding doesn't end edit in time for the Wizard page,
            //so manually force the value update:
            ((TextBox)sender).DataBindings[0].WriteValue();
            this.EnableNextStep();
        }

        private void txtTargetFilename_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {

        }
    }
}